70 | | |
71 | | == Ruby == |
72 | | |
73 | | '''''Noncomplete translation of Python-code.''''' |
74 | | |
75 | | {{{ |
76 | | def getlastsplit(firsrarfile, x) |
77 | | return firsrarfile[0..-3] + ('%03d' % (x+1)) if firsrarfile[-3..-1] == '001' |
78 | | return firsrarfile[0..-6] + ('%02d' % (x+1)) + firsrarfile[-4..-1] if firsrarfile[-11..-6] == '.part' |
79 | | return firsrarfile[0..-5] + ('%1d' % (x+1)) + firsrarfile[-4..-1] if firsrarfile[-10..-5] == '.part' |
80 | | return firsrarfile[0..-2] + ('%02d' % (x-1)) |
81 | | end |
82 | | |
83 | | def addfilehash(name, hash, seek) |
84 | | f = File.open(name, 'rb') |
85 | | f.seek(seek) |
86 | | 8192.times do |i| |
87 | | hash += f.read(8).unpack('q')[0] |
88 | | hash = hash & 0xffffffffffffffff |
89 | | end |
90 | | return hash |
91 | | end |
92 | | |
93 | | # Hash file in rar split archive. -> (size,hash) |
94 | | def OpensubtitlesHashRar(firsrarfile) |
95 | | raise 'Bad file suffix. Only .rar and .001 support.' unless firsrarfile.downcase =~ /\.rar$/ || firsrarfile =~ /\.001$/ |
96 | | |
97 | | firsrarfile = firsrarfile[0..-6] + '01' + firsrarfile[-4..-1] if firsrarfile[-11..-6] == '.part' |
98 | | |
99 | | f = File.open(firsrarfile, 'rb') |
100 | | a = f.read(4) |
101 | | raise 'ERROR: This is not rar file.' if a != 'Rar!' |
102 | | |
103 | | seek = 0 |
104 | | 4.times do |i| |
105 | | f.seek(seek) |
106 | | a = f.read(100) |
107 | | type, flag, size = a[2..7].unpack('Cvv') |
108 | | puts [type, flag, size].inspect |
109 | | if 0x74 == type |
110 | | raise 'Bad compression method! Work only for "store".' if 0x30 != a[25..26].unpack('C')[0] |
111 | | |
112 | | s_partiizebodystart = seek + size |
113 | | s_partiizebody, s_unpacksize = a[7..15].unpack('<II') |
114 | | if flag & 0x0100 |
115 | | s_unpacksize = (a[36..40].unpack('<I')[0] << 32) + s_unpacksize |
116 | | puts 'Hash untested for files biger that 2gb. May work or may generate bad hash.' |
117 | | end |
118 | | lastrarfile = getlastsplit(firsrarfile, (s_unpacksize-1) / s_partiizebody) |
119 | | hash = addfilehash(firsrarfile, s_unpacksize, s_partiizebodystart) |
120 | | hash = addfilehash(lastrarfile, hash, (s_unpacksize % s_partiizebody) + s_partiizebodystart - 65536) |
121 | | return [s_unpacksize, "%016x" % hash] |
122 | | end |
123 | | seek += size |
124 | | end |
125 | | raise 'ERROR: Not Body part in rar file.' |
126 | | end |
127 | | |
128 | | #example |
129 | | firsrarsplitfile=ARGV[0] |
130 | | size, hash = OpensubtitlesHashRar(firsrarsplitfile) |
131 | | puts('use this valuse on opensubtiles.com\n\tsize is: %d\n\thash is: %s' % [size, hash]) |
132 | | }}} |